package com.hd123.rumba.gwt.widget.client;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.DelegatingChangeListenerCollection;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.hd123.rumba.gwt.widget.client.codenamebox.CNBListener;
import com.hd123.rumba.gwt.widget.client.codenamebox.CodeNameBox;
import com.hd123.rumba.gwt.widget.client.codenamebox.UuidCodeName;

/**
 * @see {@link CodeNameBox}
 * @author caili
 * 
 */
public class LabeledCodeNameBox extends HorizontalPanel implements KeyboardListener {
  private Label label;
  private CodeNameBox codeNameBox;
  private String caption;
  private boolean required = false;
  private boolean readOnly = false;

  public LabeledCodeNameBox() {
    super();
    VerticalPanel vp = new VerticalPanel();
    vp.setSpacing(4);
    vp.add(label = new Label());
    label.setWidth("100px");
    label.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
    add(vp);
    add(codeNameBox = new CodeNameBox());
    setCellVerticalAlignment(codeNameBox, ALIGN_TOP);

    getCodeBox().addKeyboardListener(this);
  }

  public LabeledCodeNameBox(String caption) {
    this();
    setCaption(caption);
  }

  /**
   * @see {@link LabeledCodeNameBox}
   * @param caption
   * @param ucn
   */
  public LabeledCodeNameBox(String caption, UuidCodeName ucn) {
    this();
    setCaption(caption);
    codeNameBox.setUuidCodeName(ucn);
  }

  public UuidCodeName getUuidCodeName() {
    return getCodeNameBox().getUuidCodeName();
  }

  public CodeNameBox getCodeNameBox() {
    return codeNameBox;
  }

  public TextBox getCodeBox() {
    return codeNameBox.getCodeBox();
  }

  public Image getSearchButton() {
    return codeNameBox.getSearchButton();
  }

  public void addCNBListener(CNBListener listener) {
    codeNameBox.addCNBListener(listener);
  }

  public void removeCNBListener(CNBListener listener) {
    codeNameBox.removeCNBListener(listener);
  }

  public void setCaption(String caption) {
    this.caption = caption;
    if (required && !readOnly)
      DOM.setInnerHTML(label.getElement(), this.caption + "<font color='red'>*</font>");
    else
      label.setText(caption);
  }

  public String getCaption() {
    return caption;
  }

  public void setRequired(boolean required) {
    this.required = required;
    setCaption(caption);
  }

  public void setReadOnly(boolean b) {
    this.readOnly = b;
    setCaption(this.caption);
    getSearchButton().setVisible(!readOnly);
    getCodeBox().setStyleName(readOnly ? "gwt-TextBox-Disabled" : "gwt-TextBox");
    getCodeBox().setReadOnly(b);
  }

  public void onKeyDown(Widget sender, char keyCode, int modifiers) {
    keyHandler(sender, keyCode, modifiers);
  }

  public void onKeyPress(Widget sender, char keyCode, int modifiers) {
    keyHandler(sender, keyCode, modifiers);
  }

  public void onKeyUp(Widget sender, char keyCode, int modifiers) {
    keyHandler(sender, keyCode, modifiers);
  }

  private void keyHandler(Widget sender, char keyCode, int modifiers) {
    if (readOnly && sender == getCodeBox() && !Util.isNavKey(keyCode))
      getCodeBox().cancelKey();
  }

  DelegatingChangeListenerCollection changeListeners;

  public void addChangeListener(ChangeListener listener) {
    if (changeListeners == null)
      changeListeners = new DelegatingChangeListenerCollection(this, getCodeNameBox());
    changeListeners.add(listener);
  }

  public void removeChangeListener(ChangeListener listener) {
    if (changeListeners != null)
      changeListeners.remove(listener);
  }

  public void setUuidCodeName(UuidCodeName ucn) {
    getCodeNameBox().setUuidCodeName(ucn);
  }

  public void focus() {
    getCodeNameBox().focus();
  }
}
